//package com.luban.ziya.thread.lock;
//
//import sun.misc.Unsafe;
//
//import java.lang.reflect.Field;
//import java.util.concurrent.locks.AbstractOwnableSynchronizer;
//
//public class AQS extends AbstractOwnableSynchronizer {
//
//    static final class Node {
//        static final Node SHARED = new Node();
//        static final Node EXCLUSIVE = null;
//
//        static final int CANCELLED =  1;
//        static final int SIGNAL    = -1;
//        static final int CONDITION = -2;
//        static final int PROPAGATE = -3;
//
//        volatile int waitStatus;
//
//        volatile Node prev;
//
//        volatile Node next;
//
//        volatile Thread thread;
//
//        Node nextWaiter;
//
//        final boolean isShared() {
//            return nextWaiter == SHARED;
//        }
//
//        final Node predecessor() throws NullPointerException {
//            Node p = prev;
//            if (p == null)
//                throw new NullPointerException();
//            else
//                return p;
//        }
//
//        Node() {}
//
//        Node(Thread thread, Node mode) {
//            this.nextWaiter = mode;
//            this.thread = thread;
//        }
//
//        Node(Thread thread, int waitStatus) {
//            this.waitStatus = waitStatus;
//            this.thread = thread;
//        }
//    }
//
//    private transient volatile Node head;
//    private transient volatile Node tail;
//    private volatile int state;
//
//    protected final int getState() {
//        return state;
//    }
//
//    protected final void setState(int newState) {
//        state = newState;
//    }
//
//    protected final boolean compareAndSetState(int expect, int update) {
//        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
//    }
//
//    protected final boolean compareAndSetHead(Node update) {
//        return unsafe.compareAndSwapObject(this, headOffset, null, update);
//    }
//
//    protected final boolean compareAndSetTail(Node expect, Node update) {
//        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
//    }
//
//    public Node getHead() {
//        return head;
//    }
//
//    public Node getTail() {
//        return tail;
//    }
//
//    public void setHead(Node head) {
//        this.head = head;
//    }
//
//    public void setTail(Node tail) {
//        this.tail = tail;
//    }
//
//    //=====================================================================================
//    private static final Unsafe unsafe;
//    private static final long stateOffset;
//    private static final long headOffset;
//    private static final long tailOffset;
//    private static final long waitStatusOffset;
//    private static final long nextOffset;
//
//    static {
//        try {
//            Field field = Unsafe.class.getDeclaredField("theUnsafe");
//            field.setAccessible(true);
//            unsafe = (Unsafe) field.get(null);
//
//            stateOffset = unsafe.objectFieldOffset
//                    (AQS.class.getDeclaredField("state"));
//            headOffset = unsafe.objectFieldOffset
//                    (AQS.class.getDeclaredField("head"));
//            tailOffset = unsafe.objectFieldOffset
//                    (AQS.class.getDeclaredField("tail"));
//            waitStatusOffset = unsafe.objectFieldOffset
//                    (Node.class.getDeclaredField("waitStatus"));
//            nextOffset = unsafe.objectFieldOffset
//                    (Node.class.getDeclaredField("next"));
//
//        } catch (Exception ex) { throw new Error(ex); }
//    }
//}
